package ua.kharkov.knure.dereza.summarytask4.command;

import java.util.Collections;
import java.util.Comparator;
import java.util.LinkedList;
import java.util.List;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

import org.apache.log4j.Logger;

import ua.kharkov.knure.dereza.summarytask4.core.Constants;
import ua.kharkov.knure.dereza.summarytask4.db.dao.CardDAO;
import ua.kharkov.knure.dereza.summarytask4.db.dao.ClientDAO;
import ua.kharkov.knure.dereza.summarytask4.db.dao.CurrencyDAO;
import ua.kharkov.knure.dereza.summarytask4.db.dao.DAOFactory;
import ua.kharkov.knure.dereza.summarytask4.db.dao.StatusDAO;
import ua.kharkov.knure.dereza.summarytask4.db.dao.mysql.MysqlDAOFactory;
import ua.kharkov.knure.dereza.summarytask4.db.dto.CardDTO;
import ua.kharkov.knure.dereza.summarytask4.db.dto.ClientDTO;
import ua.kharkov.knure.dereza.summarytask4.db.dto.CurrencyDTO;
import ua.kharkov.knure.dereza.summarytask4.db.dto.StatusDTO;
import ua.kharkov.knure.dereza.summarytask4.db.bean.CardBean;
import ua.kharkov.knure.dereza.summarytask4.db.bean.ClientBean;

/**
 * List of cards for admin review
 * 
 * @author dereza
 * 
 */
public class AdminListCardsCommand extends Command {

	private static final long serialVersionUID = -3248489362808616707L;

	private static final Logger log = Logger
			.getLogger(AdminListCardsCommand.class);

	@Override
	public String execute(HttpServletRequest req, HttpServletResponse res) {
		log.debug("Command started");

		// gets admin's session
		HttpSession session = req.getSession(false);

		// gets ClientBean from session
		ClientBean clientBean = (ClientBean) session.getAttribute("clientbean");
		log.trace("Got admin's clientBean from session  --> " + clientBean);

		// locks malefactor
		String errorMessage = null;
		String forward = Constants.PAGE_ERROR_PAGE;
		if (clientBean == null || !clientBean.getRole().equals(Constants.ADMIN)) {
			errorMessage = "You don't have permission to perform this action";
			req.setAttribute("errorMessage", errorMessage);
			log.error("errorMessage --> " + errorMessage);
			return forward;
		}

		// creates the required DAO generator
		MysqlDAOFactory mysqlFactory = (MysqlDAOFactory) DAOFactory
				.getDAOFactory(DAOFactory.MYSQL);

		// gets cardDAO
		CardDAO cardDAO = mysqlFactory.getCardDAO();

		// gets list of all cards
		List<CardDTO> cardDTOList = cardDAO.findClientCards();
		log.trace("Found in DB: listCards --> " + cardDTOList);

		// sort cards by id
		Collections.sort(cardDTOList, new Comparator<CardDTO>() {
			public int compare(CardDTO o1, CardDTO o2) {
				int result = o1.getId() - o2.getId();
				return result == 0 ? 0 : result / (Math.abs(result));
			}
		});
		List<CardBean> cardBeanList = exchangeCardDtoTOBean(cardDTOList);
		log.trace("Replaced cardBean list --> " + cardBeanList);

		// puts cards list to the request
		req.setAttribute("cardbeanlist", cardBeanList);

		log.debug("Command finished");
		forward = Constants.PAGE_ADMIN_LIST_CARDS;
		return forward;
	}

	/**
	 * Replaces currency_id and status_id to their name and puts it to CardBean.
	 * Also puts client id, name, surname to bean;
	 * 
	 * @param List<CardDTO>
	 * @return List<CardBean>
	 */
	public static List<CardBean> exchangeCardDtoTOBean(List<CardDTO> cardDTOList) {
		log.trace("Began exchanging cardDTO to cardBean");

		// Container that will contain list of beans
		List<CardBean> cardBeanList = new LinkedList<CardBean>();
		CardBean cardBean = null;

		// creates the required DAO generator
		MysqlDAOFactory mysqlFactory = (MysqlDAOFactory) DAOFactory
				.getDAOFactory(DAOFactory.MYSQL);

		// gets currency,status and client dao
		CurrencyDAO currencyDAO = mysqlFactory.getCurrencyDAO();
		StatusDAO statusDAO = mysqlFactory.getStatusDAO();
		ClientDAO clientDAO = mysqlFactory.getClientDAO();
		for (CardDTO cardDTO : cardDTOList) {
			cardBean = new CardBean();
			cardBean.setId(cardDTO.getId());
			cardBean.setCode(cardDTO.getCode());
			cardBean.setName(cardDTO.getName());
			cardBean.setBalance(cardDTO.getBalance());

			// gets currency and status dto, does necessary query
			CurrencyDTO currencyDTO = currencyDAO.findCurrencyById(cardDTO
					.getCurrency_id());
			cardBean.setCurrency(currencyDTO.getAbbreviation());
			StatusDTO statusDTO = statusDAO.findStatusById(cardDTO
					.getStatus_id());
			cardBean.setStatus(statusDTO.getName());

			// gets id, name and surname of client
			ClientDTO clientDTO = clientDAO.findClientByCardId(cardDTO.getId());
			cardBean.setOwnerId(clientDTO.getId());
			cardBean.setOwnerName(clientDTO.getName());
			cardBean.setOwnerSurname(clientDTO.getSurName());

			// adds cardBean to list
			cardBeanList.add(cardBean);
			log.trace("added to cardBeanList --> " + cardBean);
		}
		return cardBeanList;
	}

	@Override
	public String toString() {
		return "AdminListCardsCommand";
	}
}
